<template>
  <div class="c-transaction-process"></div>
</template>

<script>
import { Toast } from "vant";
import {   PAY_WAY, PAY_WAY_LIST, getPaymentByType } from "@xiaoe/etransaction";
import { fetchPayWay, createOrder } from "./api";
import { setOrderCache } from "./utils/index";
import PayWaySelect from "./components/PayWayPopup/index.js";
import {
  DEFAULT_PAY_WAY,
  COMMON_ERROR_MSG,
  PAY_TAB_LIST,
  PAY_TYPE_LIST,
} from "./utils/constants";
import { isKSMiniProgram, enableAppPayment, isMiniEnv, isMiniProgramSdk } from '../../utils/check-env'
import { producePayParams } from "./parameter/pay-params";
import { PayBackHandler } from "./strategy/pay-back-handler";
import CopyPasswordDialog from "./components/CopyPassword/index.js";
import { Skynet, LogLevel, LogType } from "@xiaoe/skynet";
import { getMiniProType } from "../../utils/mini-pro-type";
import { isVirtualPayWay } from "../../utils/pay-way";

//config可选
export const skynet = new Skynet({
  projectName: "transaction",
  projectVersion: "v1.0.0",
  auto: false,
  url: "https://logreport.xiaoeknow.com/ecommerce/report",
});

skynet.turnOn();

export default {
  name: "CTransactionProcess",
  props: {
    // 商品信息
    goodsInfo: {
      type: Object,
      default: () => ({
      }),
    },
    // 是否需要显示花呗分期信息
    isNeedHB: {
      type: Boolean,
      default: false,
    },
    // 是否需要虚拟支付
    isNeedVirtualPay: {
      type: Boolean,
      default: false,
    },
     // 订单信息
    orderInfo: {
      type: Object,
      default: () => ({
      }),
    },
    // 支付 成功/失败 跳转地址
    jumpDataCustom: {
      type: Object,
      default: () => ({
        paySuccessUrl: "",
        payFailUrl: "",
        redirectUrl: "",
      }),
    },
    promiseResolve: {
      type: Function,
    },
  },
  data() {
    return {
      payWayInfo: {}, // 支付方式信息
      payResult: {}, //下单接口返回
      payWay: 6, // 选择的支付方式
      jumpData: {
        paySuccessUrl: this.jumpDataCustom?.paySuccessUrl,
        payFailUrl: this.jumpDataCustom?.payFailUrl,
        redirectUrl: this.jumpDataCustom?.redirectUrl,
      },
      orderPrice:0, //价格
      canClick:true, //用于下单防抖
      isLiveCommerce: this.jumpDataCustom?.redirectUrl.indexOf('isLiveCommerce') > -1, //是否直播iframe场景
    };
  },
  computed: {
    ratePrice() {
      return this.orderPrice >= 0 ? (this.orderPrice / 100).toFixed(2) : 0;
    },
    miniprogramSdkPaySetting() {
      return this.orderInfo?.miniprogramSdkPaySetting
    }
  },
  methods: {
    // 初始化数据
    async initData() {
      // 0：初始值 1：支付方式选择弹框显示 2：支付方式选择弹框关闭
      let showSelectPayWay = 0;

      let currencyInfo = {};
      this.getPayWay().then(async (res) => {
        this.payWayInfo = res
        currencyInfo = this.payWayInfo?.currency_info
        this.orderPrice = this.payWayInfo?.order_price || 0
        sessionStorage.setItem('orderPrice',this.orderPrice)
        if (!this.isNeedHB) {
          // 过滤花呗分期支付
          this.payWayInfo.hua_bei_installment_select = [];
          this.payWayInfo.list = this.payWayInfo?.list.filter(
            (res) => res.pay_way != 14
          );
        }

        if(!this.isNeedVirtualPay) {
          this.payWayInfo.list = this.payWayInfo?.list.filter(
            (res) => !isVirtualPayWay(res.pay_way)
          );
        }

        // ----- 支付方式选择 -----
        // 默认支付方式
        this.payWay = DEFAULT_PAY_WAY[0].pay_way;
        // 花呗支付信息
        let InstallmentInfo = {};

        let payWayList = this.payWayInfo?.list || [];

        // 多种支付方式
        if (payWayList.length > 1) {
          // 查找默认支付方式
          for (const ways_index in payWayList) {
            if (payWayList[ways_index]?.is_default == 1) {
              this.payWay = payWayList[ways_index].pay_way;
            }
          }
          this.payWaySelectInstance = new PayWaySelect(
            this.payWayInfo.list,
            this.payWayInfo.hua_bei_installment_select ,
            this.ratePrice,
            this.payWay,
            currencyInfo,
            this.isLiveCommerce
          );
          InstallmentInfo = await this.payWaySelectInstance.perform();
          const { way, isClose } = InstallmentInfo;
          this.payWay = way;
          // 是否是手动关闭支付方式选择弹框
          if (isClose === 1) {
            showSelectPayWay = 2;
          }
        } else if (payWayList.length === 1) {
          this.payWay = payWayList[0].pay_way;
        }
        this.promiseResolve({
          payWayInfo:  this.payWay === 14 ? InstallmentInfo :  this.payWay,
          showSelectPayWay,
        });
      }).catch((e)=>{
        Toast({
            message: e.msg || COMMON_ERROR_MSG,
            duration: 2000,
            className: 'replay-pay-toast'
          });
      });
    },
    
    // 获取支付方式
    getPayWay() {
      const params = {
        order_id:this.orderInfo.order_id
      };
      return fetchPayWay(params);
    },
    // 下单
    buy(data = {}) {
      const {  payWayInfo } = data;

      const { common_auth_code } = this.goodsInfo;
      const { order_id } = this.orderInfo
      const { payFailUrl, redirectUrl, paySuccessUrl } = this.jumpData
      let buyParams = {}
      if (!(typeof payWayInfo === 'number')) { // 花呗支付场景
     
        buyParams = {
          pay_way: payWayInfo?.way,
          installment: payWayInfo?.installment ||  0,
          installment_activity: payWayInfo?.installmentActivity || '',
          common_auth_code,
          redirect_url: redirectUrl,
          cancel_url: payFailUrl,
          is_interest_free: payWayInfo?.isInterestFree,
          order_id
        };
      } else {
        // 特殊判断： 如果是paypal支付 redirect_url取值成功的链接
        let temp_url = payWayInfo === PAY_WAY_LIST.PAYPAL ? paySuccessUrl : redirectUrl
        buyParams = {
          pay_way: payWayInfo,
          common_auth_code,
          redirect_url: temp_url,
          cancel_url: payFailUrl,
          order_id,
          initData
        };
      }

      // 终端类型
      const miniProType = getMiniProType();
      if (miniProType) {
        buyParams.mini_pro_type = miniProType;
      }

      if(!this.canClick) return
      this.canClick = false
      return createOrder(buyParams)
        .then(async (data) => {
          this.payResult = data;
          const orderId = data.order_id;

          // 设置默认支付成功、失败跳转地址
          if (!this.jumpData.paySuccessUrl) {
            this.jumpData.paySuccessUrl = `/v1/goods/pay_complete?order_id=${orderId}`;
          }
          if (!this.jumpData.payFailUrl) {
            this.jumpData.payFailUrl = `/v1/usercenter/order/order_details?order_id=${orderId}`;
          }

         await this.doPay(data);
          this.canClick = true
        })
        .catch((err) => {
          const { code, data, msg } = err;
          Toast({
            message: msg || COMMON_ERROR_MSG,
            duration: 2000,
            className: 'replay-pay-toast'
          });
          // h5缺少openid
          if (code == "30009") {
            setTimeout(() => {
              window.location.replace(data?.url);
            }, 1000);
          }
          this.canClick = true
        })
    },
    // 支付
    doPay(data) {
      // 确定支付方式
      const { need_jump, pay_config } = data;
      const { pay_way, pay_type, pay_tab } = pay_config;
      const payType = this.getCurrentPayWayName(
        pay_way,
        pay_type,
        pay_tab,
        need_jump  
      );
      // 组装对应参数
      const payInfoObj = producePayParams(
        payType,
        data,
        this.jumpData,
        "",
        this.ratePrice,
        this.goodsInfo?.spu_id,
        false
      );
      
      //缓存数据
      const { paySuccessUrl, payFailUrl } = this.jumpData;
      
      if (payType === PAY_WAY.WxH5Pay || payType === PAY_WAY.AliPay) {
        setOrderCache(paySuccessUrl, payFailUrl, data);
      }

      // 小程序
      if (isMiniEnv) {
        payInfoObj.src_url =  payFailUrl || window.location.href
        payInfoObj.back_url = paySuccessUrl || ""
      }

      // 小程序SDK环境 修改小程序支付页面
      if (isMiniProgramSdk && this.miniprogramSdkPaySetting){
        const {paymentPageUrl} = this.miniprogramSdkPaySetting;
        if (!this.miniprogramSdkPaySetting.paymentSwitch) {
          Toast({
            message: "小程序暂不支持支付",
            duration: 2000,
            className: 'replay-pay-toast'
          });
          return;
        } else if (!paymentPageUrl) {
          Toast({
            message: "小程序支付页暂未配置",
            duration: 2000,
            className: 'replay-pay-toast'
          });
          return;
        }
        payInfoObj.blankUrl = paymentPageUrl
      }

      // 跳转支付空白页上报
      if (payType == PAY_WAY.H5BlankPay) {
        skynet.report({
          details: {
            keyword: 'confirmOrderPage_order_pay_H5BlankPay',
            msg: '待支付跳转支付空白页上报日志',
            payInfoObj
          },
          level: LogLevel.INFO,
          type: LogType.CUSTOM
        })
      }
      //具体支付策略
      let payStrategy;
      
      payStrategy = getPaymentByType(payType);
      // 实施对应支付策略
      payStrategy
        .pay(payInfoObj)
        .then(() => {
          switch (payType) {
            case PAY_WAY.AliPayCommand:
              this.handleAliPay();
              break;
            case PAY_WAY.VirtualPay:
            case PAY_WAY.WxJSAPIPay:
              this.handlePayBack(data);
              break;
            case PAY_WAY.AliPay:
            case PAY_WAY.AliHuabeiPay:
            case PAY_WAY.H5BlankPay:
            case PAY_WAY.WxH5Pay:
            case PAY_WAY.PayPal:
            case PAY_WAY.MpBlankPay:
              break;
            default:
              return Promise.reject({
                errMsg: "未知支付类型",
                info: {
                  pay_way,
                  pay_type,
                  pay_tab,
                  needJump,
                  payType,
                },
              });
          }
        })
        .catch((err) => {
          this.handlePayBack(data);
          //埋点错误日志
          skynet.report({ 
            details: { 
              keyword: "confirmOrderPage_order_pay_error", 
              msg: "待支付回调捕获异常埋点",
              err, 
              payType, 
              payWay: pay_way 
            }, 
            level: LogLevel.FATAL, 
            type: LogType.CUSTOM 
          })
        });
    },
    getCurrentPayWayName(payWay, payType, payTab, needJump) {
      //快手小程序
      // console.log('999');

      if (isKSMiniProgram) {
        return PAY_WAY.KSMiniProgramPay;
      }

      //店铺小程序、鹅圈子小程序、独立圈子小程序、视频号小程序、视频号分销小程序支付
      if (isMiniEnv()) {
        return PAY_WAY.MpBlankPay;
      }
      console.log(PAY_TAB_LIST.ZFB_ZKL);

      //吱口令,优先级高，有同时花呗分期、吱口令的情况
      if (payTab === PAY_TAB_LIST.ZFB_ZKL) {
        return PAY_WAY.AliPayCommand;
      }

      //支付宝支付
      if (payWay === PAY_WAY_LIST.ALI_PAY) {
        return PAY_WAY.AliPay;
      }
       //paypal支付
      if(payWay === PAY_WAY_LIST.PAYPAL){
        return PAY_WAY.PayPal
      }
      //花呗支付
      if (payWay === PAY_WAY_LIST.ALI_HUABEI_PAY) {
        return PAY_WAY.AliHuabeiPay;
      }
      console.log((payWay === PAY_WAY_LIST.WEIXIN_PAYMENT ||
          payWay === PAY_WAY_LIST.WECHAT_PAY) &&
        payType === PAY_TYPE_LIST.H5 &&
        needJump != 1);
      if (
        (payWay === PAY_WAY_LIST.WEIXIN_PAYMENT ||
          payWay === PAY_WAY_LIST.WECHAT_PAY) &&
        payType === PAY_TYPE_LIST.H5 &&
        needJump != 1
      ) {
        return PAY_WAY.WxJSAPIPay;
      }
      if (
        (payWay === PAY_WAY_LIST.WEIXIN_PAYMENT ||
          payWay === PAY_WAY_LIST.WECHAT_PAY) &&
        payType === PAY_TYPE_LIST.APP_H5
      ) {
        return PAY_WAY.WxH5Pay;
      }
      // 印象虚拟币支付
      if (payWay === PAY_WAY_LIST.YX_VIRSUAL_PAY && enableAppPayment) {
        return PAY_WAY.VirtualPay;
      }
      // 跳空白页支付
      if (needJump == 1) {
        return PAY_WAY.H5BlankPay;
      }

      return PAY_WAY.WxJSAPIPay;
    },
    handlePayBack(order) {
      const { paySuccessUrl, payFailUrl } = this.jumpData;
      new PayBackHandler(paySuccessUrl, payFailUrl, order).perform();
    },
    handleAliPay() {
      const payConfig = {
        ...this.payResult?.pay_config,
        order_id: this.payResult?.order_id,
        trade_id: this.payResult?.trade_id,
        ...this.jumpData,
      };
      let price = sessionStorage.getItem('orderPrice') && (sessionStorage.getItem('orderPrice')/100).toFixed(2)
      new CopyPasswordDialog(payConfig, price).perform();
    },
  },
};
</script>

<style lang="scss" scoped>
.c-transaction-process {
  // font-size: 32px;
}
</style>
<style>
.replay-pay-toast{
  z-index: 9000 !important;
}
</style>
